﻿using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using YougeBookmark.Services;
using YougeBookmark.Utilities;
using System.Text.RegularExpressions;

using Timer = System.Threading.Timer;

namespace YougeBookmark.Services
{
    public class ClipboardMonitor : IDisposable
    {
        private readonly Timer _clipboardTimer;
        private readonly BookmarkManager _bookmarkManager;
        private readonly Logger _logger;
        private string _lastClipboardText = string.Empty;
        private bool _isProcessing = false;

        // URL验证正则表达式（支持无协议头格式）
        private static readonly Regex UrlRegex = new Regex(
            @"^(?:https?://)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$",
            RegexOptions.Compiled | RegexOptions.IgnoreCase);

        public event Action<string> UrlDetected;

        public ClipboardMonitor(BookmarkManager manager, Logger logger, int intervalMs = 500)
        {
            _bookmarkManager = manager ?? throw new ArgumentNullException(nameof(manager));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            _clipboardTimer = new Timer(CheckClipboard, null, intervalMs, intervalMs);
            Application.ApplicationExit += (s, e) => Dispose();
        }

        private void CheckClipboard(object state)
        {
            if (_isProcessing) return;

            try
            {
                _isProcessing = true;
                //_logger.Info($"检测: ");
                // 仅在剪贴板包含文本时处理
                //if (!Clipboard.ContainsText()) return;                

                ////_logger.Info($"检测1: ");
                //var currentText = Clipboard.GetText().Trim();
                
                if (!TryGetClipboardText(out var currentText)) return;

                //_logger.Info($"检测到文本0: {currentText}");
                if (string.IsNullOrEmpty(currentText) || currentText == _lastClipboardText) return;
                //_logger.Info($"检测到文本1: {currentText}");
                _lastClipboardText = currentText;
                // URL格式验证
                if (!IsValidUrl(currentText)) return;
               
                _logger.Info($"检测到有效URL: {currentText}");

                // 触发事件（确保在主线程执行）
                var handler = UrlDetected;
                if (handler != null)
                {
                    if (handler.Target is Control control)
                        control.BeginInvoke(handler, currentText);
                    else
                        handler.Invoke(currentText);
                }
            }
            catch (ExternalException ex) // 处理剪贴板访问冲突
            {
                _logger.Warn($"剪贴板访问冲突: {ex.Message}");
            }
            catch (Exception ex)
            {
                _logger.Error($"剪贴板监控异常: {ex.Message}", ex);
            }
            finally
            {
                _isProcessing = false;
            }
        }

        private bool TryGetClipboardText(out string text)
        {
            text = string.Empty;
            try
            {
                // 强制在STA线程访问剪贴板
                if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
                {
                    string temp = string.Empty;
                    var staThread = new Thread(() =>
                    {
                        try { temp = Clipboard.GetText(TextDataFormat.Text); }
                        catch { }
                    });
                    staThread.SetApartmentState(ApartmentState.STA);
                    staThread.Start();
                    staThread.Join(500); // 最多等待500ms
                    text = temp?.Trim() ?? string.Empty;
                    return !string.IsNullOrEmpty(temp);
                }

                if (Clipboard.ContainsText(TextDataFormat.Text))
                {
                    text = Clipboard.GetText(TextDataFormat.Text)?.Trim() ?? string.Empty;
                    return true;
                }
            }
            catch (ExternalException ex)
            {
                _logger.Warn($"剪贴板访问冲突: {ex.Message}");
            }
            return false;
        }

        /// <summary>
        /// 增强型URL验证（支持常见协议和简写格式）
        /// </summary>
        private bool IsValidUrl(string input)
        {
            if (string.IsNullOrWhiteSpace(input)) return false;

            // 补充常见协议头检测
            if (!input.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
                !input.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
            {
                input = "http://" + input; // 为验证添加临时协议头
            }

            return UrlRegex.IsMatch(input) && Uri.TryCreate(input, UriKind.Absolute, out Uri uriResult)
                && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
        }

        /// <summary>
        /// 重置监控状态（用于处理重复检测）
        /// </summary>
        public void ResetState()
        {
            _lastClipboardText = string.Empty;
        }

        public void Dispose()
        {
            _clipboardTimer?.Dispose();
            GC.SuppressFinalize(this);
        }

        ~ClipboardMonitor()
        {
            Dispose();
        }
    }
}